package com.ugoodtech.mdcc.client.controller;

/* Copyright (C) Ugoodtech, Inc - All Rights Reserved.
 * Unauthorized copying of this file, via any medium is strictly prohibited.
 * Proprietary and confidential.
 * Written by Stone Shaw.
 */

import cn.hutool.core.collection.CollectionUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mysema.query.BooleanBuilder;
import com.ugoodtech.mdcc.client.dto.JsonResponse;
import com.ugoodtech.mdcc.client.service.UserLogService;
import com.ugoodtech.mdcc.client.service.UserService;
import com.ugoodtech.mdcc.core.Constants;
import com.ugoodtech.mdcc.core.LogConstants;
import com.ugoodtech.mdcc.core.domain.QUser;
import com.ugoodtech.mdcc.core.domain.User;
import com.ugoodtech.mdcc.core.domain.UserType;
import com.ugoodtech.mdcc.core.domain.VCode;
import com.ugoodtech.mdcc.core.dto.MinipAuthRestResponse;
import com.ugoodtech.mdcc.core.model.entity.UnionIdOpenId;
import com.ugoodtech.mdcc.core.model.entity.UnionIdOpenIdExample;
import com.ugoodtech.mdcc.core.model.entity.Users;
import com.ugoodtech.mdcc.core.model.entity.UsersExample;
import com.ugoodtech.mdcc.core.model.mapper.UsersMapper;
import com.ugoodtech.mdcc.core.model.mapper.ext.UnionIdOpenIdExtMapper;
import com.ugoodtech.mdcc.core.repository.RoleRepository;
import com.ugoodtech.mdcc.core.repository.UserRepository;
import com.ugoodtech.mdcc.core.repository.VCodeRepository;
import com.ugoodtech.mdcc.core.service.WechatService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import java.util.Objects;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(description = "登录")
@RestController
@RequestMapping("/combo")
public class LoginController extends BaseController {

    @Autowired
    UserRepository userRepository;

    @Autowired
    UserService userService;

    @Autowired
    RoleRepository roleRepository;

    @Autowired
    WechatService wechatService;

    @Autowired
    private VCodeRepository vCodeRepository;

    @Autowired
    private UserLogService userLogService;
    @Autowired
    private UnionIdOpenIdExtMapper unionIdOpenIdMapper;


    @Value("${client.app.contextPath}")
    private String urlPrefix;

    /**
     * 验证码有效时间
     */
    private Long vCodeValidTime = Long.valueOf(1000 * 60 * 30);
    @Autowired
    private UnionIdOpenIdExtMapper unionIdOpenIdExtMapper;
    @Autowired
    private UsersMapper usersMapper;

    @ApiOperation("用户退出")
    @RequestMapping(value = "/userQuit", method = RequestMethod.GET)
    public JsonResponse userQuit(
        @ApiParam("微信code") @RequestParam(value = "unionId") String unionId
    ){
        if (StringUtils.isNotEmpty(unionId)) {
            BooleanBuilder booleanBuilder = new BooleanBuilder();
            QUser qUser = QUser.user;
            booleanBuilder.and(qUser.unionId.eq(unionId));
            User user = userRepository.findOne(booleanBuilder);
            if (null == user) {
                JsonResponse jsonResponse = JsonResponse.errorResponseWithError("联系管理员",
                    "未找到用户");
                return jsonResponse;
            }else  {
                user.setOpenId("");
                user.setUnionId("");
                userRepository.save(user);
                return JsonResponse.successResponse();
            }
        }
        return JsonResponse.errorResponseWithError("抱歉", "缺少用户信息");
    }

    @ApiOperation("用户登录")
    @RequestMapping(value = "/userAuth", method = RequestMethod.POST)
    public JsonResponse userAuth(
        @ApiParam("微信code") @RequestParam(value = "code", required = false) String code
    ){
        if (StringUtils.isNotEmpty(code)) {
            MinipAuthRestResponse minipAuthRestResponse  = wechatService.miniLoginAuth(code);

            BooleanBuilder booleanBuilder = new BooleanBuilder();
            QUser qUser = QUser.user;
            String unionId = minipAuthRestResponse.getData().toString();
            booleanBuilder.and(qUser.unionId.eq(unionId));
            User user = userRepository.findOne(booleanBuilder);
            Map<String, Object> userMap = new HashMap<>();
            Map<String, String> unionIdMap = new HashMap<>();
            unionIdMap.put("unionId", unionId);
            userMap.put("user", unionIdMap);
            if (null == user) {
                JsonResponse jsonResponse = JsonResponse.successResponseWithData(userMap);
                return jsonResponse;
            }else  {
                if (!user.isEnabled()) {
                    userLogService.addUserLog(user, null, LogConstants.business_type_login_fail, LogConstants.business_type_login, null, null);
                    JsonResponse jsonResponse = JsonResponse.successResponseWithData(userMap);
                    return jsonResponse;
                }

                VCode vcode = vCodeRepository.findByTelephone(user.getUsername());
                String password = user.getPassword();
                user.setEnabled(true);
                user.setUpdateTime(new Date());
                userService.changePassword(user, vcode.getvCode());
                JsonResponse jsonResponse = getAccessToken(user, vcode.getvCode());
                if (jsonResponse.isSuccess()) {
                    user.setPassword(password);
                    userRepository.save(user);
                }
                //当有其他账号有相同的openId时就清空其他账号的openId
                String openId = user.getOpenId();
                if (StringUtils.isNotEmpty(openId)) {
                    List<User> userList = userRepository.finByOpenIdAndNotEqPhone(openId,
                        user.getUsername());
                    for (User user1 : userList) {
                        user1.setOpenId("");
                        userRepository.save(user1);
                    }
                }
                return jsonResponse;
            }

        }
        return JsonResponse.errorResponseWithError("抱歉", "缺少用户信息");
    }

    @ApiOperation("用户登录")
    @RequestMapping(value = "/userLogin", method = RequestMethod.POST)
    public JsonResponse userLogin(HttpServletRequest request,
            @ApiParam("手机号码phone") @RequestParam(value = "phone") String phone,
            @ApiParam("密码password") @RequestParam(value = "vcode") String vcode,
            @ApiParam("微信code") @RequestParam(value = "unionId") String unionId
    ) throws Exception {
        System.out.println("手机号码phone" + phone);
        System.out.println("密码password" + vcode);
        System.out.println("unionId" + unionId);
        System.out.println("url " + request.getRequestURL() +" " + request.getContextPath());
        User user = userRepository.findByUserName_phone(phone);
        if (null == user) {
            return JsonResponse.errorResponseWithError("联系管理员", "未找到用户");
        }
        // if ((isSystem && user.getUserFlag() == 1 ) || (!isSystem && user.getUserFlag() == 0)){
        //     return JsonResponse.errorResponseWithError("错误","您没有权限登录该平台");
        // }
        if (!user.isEnabled()) {
            userLogService.addUserLog(user, null, LogConstants.business_type_login_fail, LogConstants.business_type_login, null, null);
            return JsonResponse.errorResponseWithError("抱歉", "用户已被禁用");
        }
//        if (StringUtils.isEmpty(code)) {
//            return JsonResponse.errorResponseWithError("抱歉", "code不能为空");
//        }
        VCode telephoneCode = vCodeRepository.findByTelephone(phone);
        if (null == telephoneCode) {
            userLogService.addUserLog(user, null, LogConstants.business_type_login_fail, LogConstants.business_type_login, null, null);
            return JsonResponse.errorResponseWithError("验证码错误", "验证码错误");
        }
        if (StringUtils.isEmpty(vcode) || !telephoneCode.getvCode().equals(vcode)) {
            userLogService.addUserLog(user, null, LogConstants.business_type_login_fail, LogConstants.business_type_login, null, null);
            return JsonResponse.errorResponseWithError("验证码错误", "验证码错误");
        }
        //判断验证码有效时间是否在30分钟内
        Long nowTime = System.currentTimeMillis();
        Long vCodeTime = telephoneCode.getUpdateTime().getTime();
        if ((nowTime - vCodeTime) > vCodeValidTime) {
            return JsonResponse.errorResponseWithError("抱歉", "验证码已过期,请重新发送验证码");
        }
        String openId = "";
        user.setUnionId(unionId);
        UnionIdOpenIdExample unionIdOpenIdExample = new UnionIdOpenIdExample();
        unionIdOpenIdExample.createCriteria().andUnionIdEqualTo(user.getUnionId());
        List<UnionIdOpenId> unionIdOpenIds = unionIdOpenIdExtMapper.selectByExample(
            unionIdOpenIdExample);
        if (CollectionUtil.isNotEmpty(unionIdOpenIds)) {
            openId = unionIdOpenIds.get(0).getOpenId();
        }
        user.setOpenId(openId);
        String password = user.getPassword();
        user.setEnabled(true);
        user.setUpdateTime(new Date());
        userService.changePassword(user, vcode);
        JsonResponse jsonResponse = getAccessToken(user, vcode);
        if (jsonResponse.isSuccess()) {
            user.setPassword(password);
            userRepository.save(user);
            //登录日志================================
            userLogService.addUserLog(user, null, LogConstants.business_type_login_success, LogConstants.business_type_login, null, null);
        } else {
            userLogService.addUserLog(user, null, LogConstants.business_type_login_fail, LogConstants.business_type_login, null, null);
        }
        return jsonResponse;
    }

    @ApiOperation("用户获取unionId")
    @RequestMapping(value = "/user/unionId", method = RequestMethod.GET)
    public MinipAuthRestResponse userLogin(
        @ApiParam("微信code") @RequestParam(value = "code") String code
    ) throws Exception {
        return wechatService.miniLoginAuth(code);

    }


    private JsonResponse getAccessToken(User user, String password) {
        if (null == user || user.isDeleted()) {
            return JsonResponse.errorResponseWithError("用户不存在", "用户不存在");
        }
        String result = oauthLogin(user.getUsername(), password);
        if (!user.isEnabled()) {
            return JsonResponse.errorResponseWithError("用户未激活", "用户未激活");
        }
        logger.info("登录结果:" + result);
        try {
            Map tokenData = new ObjectMapper().readValue(result, Map.class);
            Map<String, Object> data = new HashMap<>();
            if (null != tokenData.get("error")) {
                data.put("token", tokenData);
                return JsonResponse.errorResponseWithError("用户名密码错误", "用户名密码错误");
            }
            data.put("token", tokenData);
            data.put("user", user);
            logger.info("data:" + data);
            return JsonResponse.successResponseWithData(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return JsonResponse.errorResponseWithError("1000", "登录失败,请重试");
    }

    private String oauthLogin(String username, String password) {
        log.info(username);
        HttpClient httpclient = HttpClientBuilder.create().build();
        String encoding = oauthBasicAuthBase64();
        // 请求到本地获取token com.ugoodtech.mdcc.client.OAuth2AuthorizationServerConfig
        HttpPost httppost = new HttpPost(urlPrefix + "/oauth/token?username=" + username
                + "&password=" + password + "&grant_type=password");
        httppost.setHeader("Authorization", "Basic " + encoding);
        httppost.setHeader("Accept", "application/json");
        httppost.setHeader("Content-Type", "application/x-www-form-urlencoded");
        HttpResponse response = null;
        try {
            response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String oauthBasicAuthBase64() {
        return org.apache.commons.codec.binary.Base64.encodeBase64String((Constants.clientID + ":" + Constants.clientSecret).getBytes());
    }




    Logger logger = LoggerFactory.getLogger(LoginController.class);
}

